package com.usian.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.usian.car.CarAndUsed;
import com.usian.car.Used;
import com.usian.entity.Result;
import com.usian.entity.ResultCodeEnum;
import com.usian.feign.UserFeign;
import com.usian.mapper.CarLogMapper;
import com.usian.service.CarLogService;
import com.usian.user.Departments;
import com.usian.user.Users;
import io.swagger.v3.core.util.Json;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author:张永杰
 * @ClassName: CarLogServiceImpl
 * @Date: 2024/12/11
 * @Description:
 */
@Service
public class CarLogServiceImpl extends ServiceImpl<CarLogMapper, Used>  implements CarLogService {
    @Autowired
    private CarLogMapper carLogMapper;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Override
    public List<CarAndUsed> findAllCarlog(Integer deptId, String post) {
        //查询redis缓存，是否有用车记录，如果有则直接返回，如果没有则查询数据库后存入redis返回
        String string = redisTemplate.opsForValue().get("carlog");
        List<CarAndUsed> carAndUsedList1 = JSON.parseArray(string, CarAndUsed.class);
        if(carAndUsedList1!=null){
            return carAndUsedList1;
        }
        LambdaQueryWrapper<Used> query = Wrappers.lambdaQuery(Used.class);
        if (deptId!=null){
            query.eq(Used::getDepartmentId,deptId);
        }
        if(post!=null && !post.equals("")){
            query.eq(Used::getPost,post);
        }
        List<CarAndUsed> carAndUsedList = new ArrayList<>();
        CarAndUsed use = new CarAndUsed();
        List<Used> usedList = list(query);

        for (Used used : usedList) {
            BeanUtils.copyProperties(used,use);
            carAndUsedList.add(use);
            //远程调用用户服务，根据用户id查询用户信息
            Users users = userFeign.getUserById(used.getUserId());
            Departments dept = userFeign.getDeptById(used.getDepartmentId());
            for (CarAndUsed carAndUsed : carAndUsedList) {
                carAndUsed.setUserName(users.getUserName());
                carAndUsed.setDeptName(dept.getDepartmentName());
            }
        }
        //将查到的用车记录保存到redis缓存中
        redisTemplate.opsForValue().set("carlog", JSON.toJSONString(carAndUsedList));
        return carAndUsedList;
    }

    @Override
    public Result addCarlog(Used used) {
        //查询redis缓存，是否有用车记录，直接删除redis
        redisTemplate.delete("carlog");
        //判断选中的时间段内是否车辆已经被占用，如果被占用则不能申请记录

        Date returnTime = used.getReturnTime();
        LambdaQueryWrapper<Used> query = Wrappers.lambdaQuery(Used.class);
        query.eq(Used::getCarNumber,used.getCarNumber());
        List<Used> list = list(query);
        for (Used one : list) {
            if(one!=null){
                //TODO 根据车牌号远程调用汽车服务，查询汽车详情，判断车辆是否已经报废，如果已经报废则不能申请
                //TODO 如果汽车没有报废，则判断汽车状态是否在使用状态，如果在使用状态，则直接返回提示信息
                //判断时间段是否重叠
                //申请时间，归还时间
                /**
                 * 如果申请时间在归还时间之前，这辆车不能申请
                 */
                if(one.getUsedTime().before(returnTime)){
                    return  Result.build(null,ResultCodeEnum.ERRORUSED);
                }
            }
        }
        //根据用户id查询当前记录表中用户是否已经在用车记录，如果在时间范围内则不能同时申请2辆车
        LambdaQueryWrapper<Used> query1 = Wrappers.lambdaQuery(Used.class);
        query1.eq(Used::getUserId,used.getUserId());
        List<Used> list1 = list(query1);
        for (Used one : list1) {
            if(one!=null){
                if(one.getUsedTime().before(returnTime) ){
                    return  Result.build(null,ResultCodeEnum.ERRORUSERUSED);
                }
            }
        }
        save(used);
        return Result.build(null,ResultCodeEnum.SUCCESS);
    }
}
